home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / commands / elvis / input.c < prev    next >
C/C++ Source or Header  |  1990-07-15  |  6KB  |  308 lines

  1. /* input.c */
  2.  
  3. /* Author:
  4.  *    Steve Kirkendall
  5.  *    16820 SW Tallac Way
  6.  *    Beaverton, OR 97006
  7.  *    kirkenda@jove.cs.pdx.edu, or ...uunet!tektronix!psueea!jove!kirkenda
  8.  */
  9.  
  10.  
  11. /* This file contains the input() function, which implements vi's INPUT mode */
  12.  
  13. #include "vi.h"
  14.  
  15.  
  16. /* This function allows the user to replace an existing (possibly zero-length)
  17.  * chunk of text with typed-in text.  It returns the MARK of the last character
  18.  * that the user typed in.
  19.  */
  20. MARK input(from, to, when)
  21.     MARK    from;    /* where to start inserting text */
  22.     MARK    to;    /* extent of text to delete */
  23.     int    when;    /* either WHEN_VIINP or WHEN_VIREP */
  24. {
  25.     char    key[2];    /* key char followed by '\0' char */
  26.     char    *build;    /* used in building a newline+indent string */
  27.     char    *scan;    /* used while looking at the indent chars of a line */
  28.     MARK    m;
  29.  
  30. #ifdef DEBUG
  31.     /* if "from" and "to" are reversed, complain */
  32.     if (from > to)
  33.     {
  34.         msg("ERROR: input(%ld:%d, %ld:%d)",
  35.             markline(from), markidx(from),
  36.             markline(to), markidx(to));
  37.         return MARK_UNSET;
  38.     }
  39. #endif
  40.  
  41.     key[1] = 0;
  42.  
  43.     /* if we're replacing text with new text, save the old stuff */
  44.     /* (Alas, there is no easy way to save text for replace mode) */
  45.     if (from != to)
  46.     {
  47.         cut(from, to);
  48.     }
  49.  
  50.     ChangeText
  51.     {
  52.         /* if doing a dot command, then reuse the previous text */
  53.         if (doingdot)
  54.         {
  55.             /* delete the text thats there now */
  56.             if (from != to)
  57.             {
  58.                 delete(from, to);
  59.             }
  60.  
  61.             cutname('.');
  62.             cursor = paste(from, FALSE, TRUE) + 1L;
  63.         }
  64.         else
  65.         {
  66.             /* if doing a change within the line... */
  67.             if (from != to && markline(from) == markline(to))
  68.             {
  69.                 /* mark the end of the text with a "$" */
  70.                 change(to - 1, to, "$");
  71.             }
  72.             else
  73.             {
  74.                 /* delete the old text right off */
  75.                 if (from != to)
  76.                 {
  77.                     delete(from, to);
  78.                 }
  79.                 to = from;
  80.             }
  81.  
  82.             /* handle autoindent of the first line, maybe */
  83.             cursor = from;
  84.             if (*o_autoindent && markline(cursor) > 1L && markidx(cursor) == 0)
  85.             {
  86.                 /* Only autoindent blank lines. */
  87.                 pfetch(markline(cursor));
  88.                 if (plen == 0)
  89.                 {
  90.                     /* Okay, we really want to autoindent */
  91.                     pfetch(markline(cursor) - 1L);
  92.                     for (scan = ptext, build = tmpblk.c;
  93.                          *scan == ' ' || *scan == '\t';
  94.                          )
  95.                     {
  96.                         *build++ = *scan++;
  97.                     }
  98.                     if (build > tmpblk.c)
  99.                     {
  100.                         *build = '\0';
  101.                         add(cursor, tmpblk.c);
  102.                         cursor += (build - tmpblk.c);
  103.                     }
  104.                 }
  105.             }
  106.  
  107.             /* repeatedly add characters from the user */
  108.             for (;;)
  109.             {
  110.                 /* Get a character */
  111.                 redraw(cursor, TRUE);
  112.                 key[0] = getkey(when);
  113.  
  114.                 /* if whitespace & wrapmargin is set & we're
  115.                 /* past the warpmargin, then change the
  116.                 /* whitespace character into a newline
  117.                  */
  118.                 if ((*key == ' ' || *key == '\t')
  119.                  && *o_wrapmargin != 0)
  120.                 {
  121.                     pfetch(markline(cursor));
  122.                     if (idx2col(cursor, ptext, TRUE) > COLS - (*o_wrapmargin & 0xff))
  123.                     {
  124.                         *key = '\n';
  125.                     }
  126.                 }
  127.  
  128.                 /* process it */
  129.                 switch (*key)
  130.                 {
  131.                   case ctrl('['):
  132.                     goto BreakBreak;
  133.  
  134.                   case ctrl('U'):
  135.                     if (markline(cursor) == markline(from))
  136.                     {
  137.                         cursor == from;
  138.                     }
  139.                     else
  140.                     {
  141.                         cursor &= ~(BLKSIZE - 1);
  142.                     }
  143.                     break;
  144.  
  145.                   case ctrl('D'):
  146.                   case ctrl('T'):
  147.                     mark[27] = cursor;
  148.                     cmd_shift(cursor, cursor, *key == ctrl('D') ? CMD_SHIFTL : CMD_SHIFTR, TRUE, "");
  149.                     if (mark[27])
  150.                     {
  151.                         cursor = mark[27];
  152.                     }
  153.                     else
  154.                     {
  155.                         cursor = movefront(cursor, 0L);
  156.                     }
  157.                     break;
  158.  
  159.                   case '\b':
  160.                     if (cursor <= from)
  161.                     {
  162.                         beep();
  163.                     }
  164.                     else if (markidx(cursor) == 0)
  165.                     {
  166.                         cursor -= BLKSIZE;
  167.                         pfetch(markline(cursor));
  168.                         cursor += plen;
  169.                     }
  170.                     else
  171.                     {
  172.                         cursor--;
  173.                     }
  174.                     break;
  175.  
  176.                   case ctrl('W'):
  177.                     m = movebword(cursor, 1L);
  178.                     if (markline(m) == markline(cursor) && m >= from)
  179.                     {
  180.                         cursor = m;
  181.                         if (from > cursor)
  182.                         {
  183.                             from = cursor;
  184.                         }
  185.                     }
  186.                     else
  187.                     {
  188.                         beep();
  189.                     }
  190.                     break;
  191.  
  192.                   case '\n':
  193.                   case '\r':
  194.                     build = tmpblk.c;
  195.                     *build++ = '\n';
  196.                     if (*o_autoindent)
  197.                     {
  198.                         pfetch(markline(cursor));
  199.                         for (scan = ptext; *scan == ' ' || *scan == '\t'; )
  200.                         {
  201.                             *build++ = *scan++;
  202.                         }
  203.                     }
  204.                     *build = 0;
  205.                     if (cursor >= to && when != WHEN_VIREP)
  206.                     {
  207.                         add(cursor, tmpblk.c);
  208.                     }
  209.                     else
  210.                     {
  211.                         change(cursor, to, tmpblk.c);
  212.                     }
  213.                     redraw(cursor, TRUE);
  214.                     to = cursor = (cursor & ~(BLKSIZE - 1))
  215.                             + BLKSIZE
  216.                             + (int)(build - tmpblk.c) - 1;
  217.                     break;
  218.  
  219.                   case ctrl('A'):
  220.                     if (cursor < to)
  221.                     {
  222.                         delete(cursor, to);
  223.                     }
  224.                     cutname('.');
  225.                     to = cursor = paste(cursor, FALSE, TRUE) + 1L;
  226.                     break;
  227.  
  228.                   case ctrl('V'):
  229.                     if (cursor >= to && when != WHEN_VIREP)
  230.                     {
  231.                         add(cursor, "^");
  232.                     }
  233.                     else
  234.                     {
  235.                         change(cursor, to, "^");
  236.                     }
  237.                     redraw(cursor, TRUE);
  238.                     *key = getkey(0);
  239.                     if (*key == '\n')
  240.                     {
  241.                         /* '\n' too hard to handle */
  242.                         *key = '\r';
  243.                     }
  244.                     change(cursor, cursor + 1, key);
  245.                     cursor++;
  246.                     if (cursor > to)
  247.                     {
  248.                         to = cursor;
  249.                     }
  250.                     break;
  251.  
  252.                   case ctrl('L'):
  253.                   case ctrl('R'):
  254.                     redraw(MARK_UNSET, FALSE);
  255.                     break;
  256.  
  257.                   default:
  258.                     if (cursor >= to && when != WHEN_VIREP)
  259.                     {
  260.                         add(cursor, key);
  261.                         cursor++;
  262.                         to = cursor;
  263.                     }
  264.                     else
  265.                     {
  266.                         pfetch(markline(cursor));
  267.                         if (markidx(cursor) == plen)
  268.                         {
  269.                             add(cursor, key);
  270.                         }
  271.                         else
  272.                         {
  273.                             change(cursor, cursor + 1, key);
  274.                         }
  275.                         cursor++;
  276.                     }
  277.                 } /* end switch(*key) */
  278.             } /* end for(;;) */
  279. BreakBreak:;
  280.  
  281.             /* delete any excess characters */
  282.             if (cursor < to)
  283.             {
  284.                 delete(cursor, to);
  285.             }
  286.  
  287.         } /* end if doingdot else */
  288.  
  289.     } /* end ChangeText */
  290.  
  291.     /* put the new text into a cut buffer for possible reuse */
  292.     if (!doingdot)
  293.     {
  294.         blksync();
  295.         cutname('.');
  296.         cut(from, cursor);
  297.     }
  298.  
  299.     /* move to last char that we inputted, unless it was newline */
  300.     if (markidx(cursor) != 0)
  301.     {
  302.         cursor--;
  303.     }
  304.  
  305.     rptlines = 0L;
  306.     return cursor;
  307. }
  308.